try:
    from .path_generator import BlockUtil, ConnectorGenerator
except:
    from path_generator import BlockUtil, ConnectorGenerator

try:
    from .path_helper import *
except:
    from path_helper import *
from OCC.Core.BRep import BRep_Builder
from OCC.Core.TopoDS import TopoDS_Compound


class ClampComposition():
    def __init__(self,points_pair,clamp,clamp_mseh,work_mesh,res,rps,*args,**kwargs):
        self.points_pair = points_pair
        self.clamp = clamp
        self.res = res
        self.rps = rps
        self.BG = BlockUtil(self.points_pair)
        self.CG = ConnectorGenerator(clamp_mseh,work_mesh,self.get_entry_exit(),res)

    @staticmethod
    def projection_distance(rps, start):
        vector1 = np.array(rps[:2])
        vector2 = np.array(start[:2])
        distance = np.linalg.norm(vector1 - vector2)
        return distance

    def create_boxes(self):
        start_boxes = []
        target_boxes = []
        for i in range(len(self.points_pair)):
            start_boxes.append(self.BG.create_box(self.points_pair[i]['start'],axis_x=self.points_pair[i]['start_axis'],dx=65,dy=20,dz=20.0,normal=self.points_pair[i]['start_normal']))
            if ClampComposition.projection_distance(self.rps,self.points_pair[i]['target'])>=80:
                target_boxes.append(self.BG.create_box(self.points_pair[i]['target'],axis_x=self.points_pair[i]['target_axis'],dx=65,dy=20,dz=20.0,normal=self.points_pair[i]['target_normal']))
        return start_boxes,target_boxes

    def get_entry_exit(self):
        entries = []
        exits = []
        for i in range(len(self.points_pair)):
            entries.append(self.BG.get_entry(i))
            if ClampComposition.projection_distance(self.rps, self.points_pair[i]['target']) <= 80:
                if self.res<=2:
                    exits.append(self.rps+self.points_pair[i]['target_normal']*2*self.res)
                else:
                    exits.append(self.rps + self.points_pair[i]['target_normal'] * 1 * self.res)
            else:
                exits.append(self.BG.get_exit(i))
        return entries,exits

    def create_connecters(self):
        prism_list = self.CG.get_compound()
        return prism_list

    def get_compound(self):
        #start_boxes, target_boxes = self.create_boxes()
        connecters = self.create_connecters()
        compound = TopoDS_Compound()
        B = BRep_Builder()
        B.MakeCompound(compound)
        # for i in range(len(start_boxes)):
        #     B.Add(compound, start_boxes[i])
        #
        # if len(target_boxes)==0:
        #     pass
        # else:
        #     for i in range(len(target_boxes)):
        #         B.Add(compound, target_boxes[i])

        for connecter in connecters:
            B.Add(compound,connecter)
        B.Add(compound, self.clamp.compound())

        return compound

    def get_boxes_dict(self):
        pass

    def get_connecter_dict(self):
        return self.CG.to_json()

    def to_json(self):

        part_list=[
                    {},
                    {}
                ]
        ans = {}
        ans['version'] = "Eric"
        ans['PartInfo'] = part_list
        return ans
        # for ele in self.elements.keys():
        #     ele_child = {}
        #     ele_child['name'] = ele
        #     ele_child['category'] = self.elements[ele]['category']
        #     ele_child['desc'] = self.elements[ele]['desc']
        #     ans['elements'].append(ele_child)
        # for tran in self.trans.keys():
        #     tran_child = {'group': self.trans[tran]['group']}
        #     if 'point2point' in self.trans[tran].keys():
        #         tran_child['point2point'] = self.trans[tran]['point2point']
        #     if 'move' in self.trans[tran].keys():
        #         tran_child['move'] = self.trans[tran]['move']
        #     if 'rotate' in self.trans[tran].keys():
        #         tran_child['rotate'] = self.trans[tran]['rotate']
        #     ans['trans'].append(tran_child)